package com.spring.client.controller;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;
import org.springframework.util.Assert;

public class HessianClientBeanFactory implements ApplicationContextAware {

	private static final Logger LOGGER = LoggerFactory.getLogger(HessianClientBeanFactory.class);

	private static final String DEFAULT_SUFFIX = ".htm";

	/**
	 * 访问地址
	 */
	protected String serverUrl;

	/**
	 * server---接口包扫描
	 */
	protected String[] scanPackages;

	/**
	 * hessian-server方法是否允许重载
	 */
	protected boolean overloadEnabled;


	@Override
	public void setApplicationContext(ApplicationContext applicationContext) {
		Assert.notNull(serverUrl, "远程Hessian访问地址不能为空。");
		Assert.notNull(scanPackages, "scanPackages不能为空。");
		ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();

		List<String> asList = Arrays.asList(scanPackages);
		LOGGER.info("初始化扫描Hessian信息开始！包路径:{}", asList);

		Set<Class<?>> classes = ClassUtils.getClasses(asList);

		for (Class<?> hessianClass : classes) {
			if (hessianClass.isInterface()) {
				String simpleName = hessianClass.getSimpleName();
				String serviceInterface = hessianClass.getName();
				String serviceUrl = serverUrl + StringUtils.uncapitalize(simpleName) + DEFAULT_SUFFIX;
				int connTimeout = 60;
				int readTimeout = 60;
				LOGGER.info("Register HessianClientBean=>\n {} || {} || {} || {}", serviceUrl, serviceInterface, connTimeout, readTimeout);
				registerBeanDefinition(beanFactory, serviceUrl, simpleName, serviceInterface, connTimeout, readTimeout);
			}
		}
	}

	/**
	 * 创建bean并且放入springBean工厂，取代xml的繁琐配置
	 *
	 * @param beanFactory      bean工厂
	 * @param serviceUrl       bean工厂
	 * @param serviceInterface service--bean 的名称
	 * @param connTimeout      connTimeout
	 * @param readTimeout      readTimeout
	 */
	private void registerBeanDefinition(DefaultListableBeanFactory beanFactory, String serviceUrl, String beanName, String serviceInterface, int connTimeout, int readTimeout) {
		// 通过BeanDefinitionBuilder创建bean定义
		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(HessianProxyFactoryBean.class);
		beanDefinitionBuilder.addPropertyValue("serviceUrl", serviceUrl);
		beanDefinitionBuilder.addPropertyValue("serviceInterface", serviceInterface);
		beanDefinitionBuilder.addPropertyValue("overloadEnabled", overloadEnabled);
		beanDefinitionBuilder.addPropertyValue("connectTimeout", connTimeout * 1000);
		beanDefinitionBuilder.addPropertyValue("readTimeout", readTimeout * 1000);

		// 注册bean
		beanFactory.registerBeanDefinition(StringUtils.uncapitalize(beanName), beanDefinitionBuilder.getRawBeanDefinition());
	}

	public void setServerUrl(String serverUrl) {
		this.serverUrl = serverUrl;
	}

	public void setScanPackages(String[] scanPackages) {
		this.scanPackages = scanPackages;
	}

	public void setOverloadEnabled(boolean overloadEnabled) {
		this.overloadEnabled = overloadEnabled;
	}
}